﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Evolution
{
    class Evolution
    {
        static void Main()
        {
            MatrixControl mc;
            ConsoleKeyInfo cki;

            //size of matrix
            int mRows = 30;  
            int mColumns = 30;

            Console.SetWindowSize(40,40);
            Console.Title = "Homework #2: Evolution";
            mc=new MatrixControl(mRows,mColumns);
            mc.PrintMatrix();
               
            Console.SetCursorPosition(1, 1);
                do
                {
                    cki = Console.ReadKey();

                    switch (cki.Key)
                    {
                        case ConsoleKey.RightArrow:
                                StandStill(mc);
                                //move to the right if we still in matrix
                                if (Console.CursorLeft < mColumns-1)  //<29
                                    Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
                            break;
                        case ConsoleKey.LeftArrow:
                                StandStill(mc);
                                //move to the left if we still in matrix
                                if (Console.CursorLeft > 0)
                                    Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                            break;
                        case ConsoleKey.UpArrow:
                                StandStill(mc);
                                //move to the right if we still in matrix
                                if (Console.CursorTop > 0)
                                    Console.SetCursorPosition(Console.CursorLeft, Console.CursorTop - 1);
                            break;
                        case ConsoleKey.DownArrow:
                                StandStill(mc);
                                //move to the right if we still in matrix
                                if (Console.CursorTop < mRows-1)  //<29
                                Console.SetCursorPosition(Console.CursorLeft, Console.CursorTop + 1);
                            break;
                        case ConsoleKey.Spacebar:
                                int count = 0;
                                                           
                                if ((Console.CursorLeft > 1) & (Console.CursorTop > 0))
                                    if (mc.GetMatrixElement(Console.CursorLeft - 1, Console.CursorTop - 1) == '*') count++;
                                if (Console.CursorLeft > 1)
                                    if (mc.GetMatrixElement(Console.CursorLeft - 1, Console.CursorTop) == '*') count++;
                                if ((Console.CursorLeft > 1) & (Console.CursorTop < mRows - 1))  
                                    if (mc.GetMatrixElement(Console.CursorLeft - 1, Console.CursorTop + 1) == '*') count++;
                                if (Console.CursorTop > 0)
                                    if (mc.GetMatrixElement(Console.CursorLeft, Console.CursorTop - 1) == '*') count++;
                                if (Console.CursorTop < mRows - 1)
                                    if (mc.GetMatrixElement(Console.CursorLeft, Console.CursorTop + 1) == '*') count++;
                                if ((Console.CursorLeft < mColumns) & (Console.CursorTop > 0))
                                    if (mc.GetMatrixElement(Console.CursorLeft + 1, Console.CursorTop - 1) == '*') count++;
                                if (Console.CursorLeft < mColumns)
                                    if (mc.GetMatrixElement(Console.CursorLeft + 1, Console.CursorTop) == '*') count++;
                                if ((Console.CursorLeft < mColumns) & (Console.CursorTop < mRows - 1))
                                    if (mc.GetMatrixElement(Console.CursorLeft + 1, Console.CursorTop + 1) == '*') count++;
                                

                                if (mc.GetMatrixElement(Console.CursorLeft, Console.CursorTop) == '*')
                                {
                                    //draw space                         //TODO: mColumns from 1 to 30 ??? But mRows from 0 to 29 ???
                                    if ((count == 8) |
                                       ((count == 3) & (((Console.CursorLeft == 1) & (Console.CursorTop == 0)) |
                                                          ((Console.CursorLeft == 1) & (Console.CursorTop == mRows-1)) |
                                                          ((Console.CursorLeft == mColumns) & (Console.CursorTop == 0)) |
                                                          ((Console.CursorLeft == mColumns) & (Console.CursorTop == mRows-1)))) |
                                       ((count == 5) & ((Console.CursorLeft == 1) | (Console.CursorLeft == mColumns) |
                                                                (Console.CursorTop == 0) | (Console.CursorTop == mRows-1))))
                                    {
                                        Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                                        Console.Write('_');
                                        mc.SetMatrixElement(Console.CursorLeft, Console.CursorTop, '_');
                                        Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                                    } else StandStill(mc);
                                }
                                else
                                    {
                                        //draw star
                                        if (count > 1)
                                        {
                                            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                                            Console.Write('*');
                                            mc.SetMatrixElement(Console.CursorLeft, Console.CursorTop, '*');
                                            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                                        } else StandStill(mc);
                                    };
                            break;
                      /*  case ConsoleKey.Enter:         //TODO: problem with ENTER, BackSpace, Tab
                            StandStill(mc);
                            break;*/
                        default:
                            StandStill(mc);
                            break;
                    }
                } while (cki.Key != ConsoleKey.Escape);
        }

        //stand still without element removal
        static void StandStill(MatrixControl mc1)
        {
            char ch;
            ch = mc1.GetMatrixElement(Console.CursorLeft, Console.CursorTop);

            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
            Console.Write(ch);
            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
        }

    }

    class MatrixControl
    {
        char[,] matrixChar;
        byte[,] matrixByte;

        public MatrixControl(int rows, int columns)
        {
            matrixChar = new char[rows,columns]; 
            matrixByte = new byte[rows, columns];

            Random randomizer = new Random();
            for (int i = 0; i < matrixByte.GetLength(0); i++)
            {
                for (int j = 0; j < matrixByte.GetLength(1); j++)
                {
                    matrixByte[i, j] = (byte)randomizer.Next(0,3); //3 - in order to obtain not so many stars
                    if (matrixByte[i, j] == 1)
                    {
                        matrixChar[i, j] = '*';
                    }
                    else matrixChar[i,j]='_';
                }
            }
        }

        public void PrintMatrix()
        {
            for (int j = 0; j < matrixChar.GetLength(0); j++)
            {
                for (int i = 0; i < matrixChar.GetLength(1); i++)
                    Console.Write(matrixChar[j,i]);
                Console.WriteLine();
            }
        }

        public char GetMatrixElement(int cursorX,int cursorY)
        {
            char element;
            element=matrixChar[cursorY,cursorX-1];

            return element;
        }

        public void SetMatrixElement(int cursorX, int cursorY, char element)
        {
            matrixChar[cursorY , cursorX-1 ]=element;
        }
    }
}
